package cn.cxj.order.service.impl;

import cn.cxj.basic.constant.OrderTypeConstants;
import cn.cxj.basic.exception.BusinessException;
import cn.cxj.basic.service.impl.BaseServiceImpl;
import cn.cxj.basic.util.CodeGenerateUtils;
import cn.cxj.basic.util.DistanceUtil;
import cn.cxj.basic.util.Point;
import cn.cxj.basic.util.QuartzUtils;
import cn.cxj.order.domain.OrderAddress;
import cn.cxj.order.domain.Product;
import cn.cxj.order.domain.ProductOrder;
import cn.cxj.order.domain.ProductOrderDetail;
import cn.cxj.order.mapper.OrderAddressMapper;
import cn.cxj.order.mapper.ProductMapper;
import cn.cxj.order.mapper.ProductOrderDetailMapper;
import cn.cxj.order.mapper.ProductOrderMapper;
import cn.cxj.order.service.IProductOrderService;
import cn.cxj.org.domain.Shop;
import cn.cxj.org.mapper.ShopMapper;
import cn.cxj.pay.domain.AlipayInfo;
import cn.cxj.pay.domain.PayBill;
import cn.cxj.pay.mapper.AlipayInfoMapper;
import cn.cxj.pay.mapper.PayBillMapper;
import cn.cxj.pay.service.IPayService;
import cn.cxj.quartz.domain.QuartzJobInfo;
import cn.cxj.quartz.jobs.ProductOrderJob;
import cn.cxj.quartz.service.IQuartzService;
import cn.cxj.user.domain.Logininfo;
import cn.cxj.user.domain.User;
import cn.cxj.user.domain.UserAddress;
import cn.cxj.user.mapper.UserAddressMapper;
import cn.cxj.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ProductOrderServiceImpl extends BaseServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired
    private ProductOrderMapper productOrderMapper;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ProductOrderDetailMapper productOrderDetailMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PayBillMapper payBillMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private AlipayInfoMapper alipayInfoMapper;

    @Autowired
    private IPayService payService;

    @Autowired
    private IQuartzService quartzService;

    @Override
    @Transactional
    public String submit(Map<String, String> params, Logininfo logininfo) {
        // 获取前端传过来的参数
        String serviceMethod = params.get("service_method");
        Long addressId = Long.valueOf(params.get("address_id"));
        Integer payMethod = Integer.valueOf(params.get("pay_method"));
        Long productId = Long.valueOf(params.get("product_id"));
        // 判断一下是否登陆,因为注释掉了登陆拦截器
        if (logininfo == null) {
            throw new BusinessException("登陆用户不能为空");
        }
        // 根据登陆信息的id查询当前登陆人的信息
        User user = userMapper.loadByLogininfoId(logininfo.getId());
        // 获取当前下单的服务信息
        Product product = productMapper.loadById(productId);
        // 销量加1
        product.setSalecount(product.getSalecount() + 1);
        productMapper.update(product);
        // 根据地址就近选择一家商家接收该订单
        List<Shop> shops = shopMapper.loadAll();
        UserAddress userAddress = userAddressMapper.loadByAddressId(addressId);
        Point point = DistanceUtil.getPoint(userAddress.getFullAddress());
        Shop nearestShop = DistanceUtil.getNearestShop(point, shops);
        // 生成一个服务订单,保存到数据库,返回自增主键
        ProductOrder productOrder = initProductOrder(product, user);
        productOrder.setAddress_id(addressId);
        productOrder.setShop_id(nearestShop.getId());
        productOrderMapper.save(productOrder);
        // 生成一个服务信息的快照,保存到t_product_order_detail
        ProductOrderDetail productOrderDetail = initProductOrderDetail(product);
        productOrderDetail.setOrder_id(productOrder.getId());
        productOrderDetailMapper.save(productOrderDetail);
        // 生成一个地址快照,保存到t_order_address
        OrderAddress orderAddress = initOrderAddress(userAddress);
        orderAddress.setOrder_id(productOrder.getId());
        orderAddress.setOrderSn(productOrder.getOrderSn());
        orderAddressMapper.save(orderAddress);
        // 生成支付单
        PayBill payBill = initPayBill(productOrder, payMethod);
        payBill.setShopName(nearestShop.getName());
        payBillMapper.save(payBill);
        // 根据商铺id查询到商铺的私钥,appid,支付宝公钥
        AlipayInfo alipayInfo = alipayInfoMapper.loadByShopId(payBill.getShop_id());
        String result = payService.pay(alipayInfo, payBill);

        // 添加定时任务
        Map<String, Object> map = new HashMap<>();
        map.put("orderSn", payBill.getOrderSn());
        QuartzJobInfo quartzJobInfo = new QuartzJobInfo();
        quartzJobInfo.setFireDate(payBill.getLastPayTime());
        quartzJobInfo.setJobName(payBill.getOrderSn());
        quartzJobInfo.setType(ProductOrderJob.class);
        quartzService.addJob(quartzJobInfo);

        return result;
    }

    private OrderAddress initOrderAddress(UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        return orderAddress;
    }

    /**
     * 初始化支付单
     * @param productOrder
     * @param payMethod
     * @return
     */
    private PayBill initPayBill(ProductOrder productOrder, Integer payMethod) {
        PayBill payBill = new PayBill();
        BeanUtils.copyProperties(productOrder, payBill);
        payBill.setMoney(productOrder.getPrice());
        payBill.setCreateTime(new Date());
        payBill.setBusinessKey(productOrder.getId());
        payBill.setBusinessType(OrderTypeConstants.PRODUCT_ORDER);
        payBill.setPayChannel(payMethod);
        return payBill;
    }

    private ProductOrderDetail initProductOrderDetail(Product product) {
        ProductOrderDetail productOrderDetail = new ProductOrderDetail();
        BeanUtils.copyProperties(product, productOrderDetail);
        productOrderDetail.setProduct_id(product.getId());
        productOrderDetail.setId(null);
        return productOrderDetail;
    }

    private ProductOrder initProductOrder(Product product, User user) {
        ProductOrder productOrder = new ProductOrder();
        productOrder.setDigest("[服务订单]"+product.getName());
        productOrder.setPrice(product.getSaleprice());
        productOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        productOrder.setLastPayTime(new Date(System.currentTimeMillis() + 1000*60));
        productOrder.setUser_id(user.getId());
        productOrder.setProduct_id(product.getId());
        productOrder.setState(0);
        return productOrder;
    }
}
